package com.example.myaptuselearing

import android.app.Activity
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.widget.Button
import android.widget.Toast
import com.example.myaptuselearing.annotation_introduce.AnnotationInit
import com.example.myaptuselearing.annotation_introduce.BindViewClass
import com.example.myaptuselearing.annotation_introduce.BindViewRuntime
import com.example.myaptuselearing.bindview.ButtonKnife
import java.lang.Exception


class MainActivity : AppCompatActivity() {

    companion object{
        private const val TAG = "MainActivity"
    }
    @AnnotationInit(address = "hangzhoubt_1")
    @BindViewRuntime(value = R.id.bt_1)
    lateinit var bt1:Button

    @BindViewClass(value = R.id.bt_2)
    lateinit var bt2:Button

    lateinit var btVerify:Button

    @AnnotationInit(address = "hangzhou")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        injectBindViewRuntime(this)
//        injectBindViewClass(this)//编译时注解，不会保留到运行时，所以反射获取不到
//        ButtonKnife.bind(this)//通过设计构建不同的activity，然后 findViewById(R.id.bt_start)
        btVerify = findViewById(R.id.bt_start)
        btVerify.setOnClickListener{
            Log.d(TAG, "onCreate: ${bt1.text}")
            Log.d(TAG, "onCreate: ${bt2.text}")

        }

        findViewById<Button>(R.id.bt_start_second).setOnClickListener{
            startActivity(Intent(this,VerifyCustomAnnotationActivity::class.java))
        }
    }


    /**运行时获取
     * 这些get方法之所以慢是因为根据方法名或字段名在获取method或field时类似于在class所在方法区做遍历匹配，
     * 拿到之后要么反射执行方法，要么反射field赋值；
     * 而如果是直接调用则是通过将方法或属性的符号引用转变为直接引用找到方法或字段的所在，直接进行操作
     *
     * */
  private  fun injectBindViewRuntime(activity: Activity) {
        try {
            //declaredFields 获取当前对象的所有属性
            val fields = activity.javaClass.declaredFields
            if (fields != null && fields.isNotEmpty()) {
                for (field in fields) {
                    //getAnnotation	返回该类中与参数类型匹配的公有注解对象
                    val viewInject: BindViewRuntime? = field.getAnnotation(BindViewRuntime::class.java)
                    //返回当前对象所有的公有注解对象
                    val annotations = field.annotations

                    viewInject?.let{viewInject ->
                        val viewId: Int = viewInject.value
                        try {
                            field.isAccessible = true
                            field[activity] = activity.findViewById(viewId)
                        } catch (e: Exception) {
                            e.printStackTrace()
                        }
                    }

                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }
    /**编译时获取，报错*/
    private  fun injectBindViewClass(activity: Activity) {
        try {
            val fields = activity.javaClass.declaredFields
            if (fields != null && fields.isNotEmpty()) {
                for (field in fields) {
                    val viewInject: BindViewClass? = field.getAnnotation(BindViewClass::class.java)

                    viewInject?.let{viewInject ->
                        val viewId: Int = viewInject.value
                        try {
                            field.isAccessible = true
                            field[activity] = activity.findViewById(viewId)
                        } catch (e: Exception) {
                            e.printStackTrace()
                        }
                    }

                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }
}